#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<netdb.h>
#include<time.h>
#include<fcntl.h>
#include<dirent.h>
#include<getopt.h>
#include<libgen.h>
#include<fcntl.h>
#include<unistd.h>
#include<signal.h>
#include"client_temperature.h"
#include"mosquitto.h"
#include"client_time.h"
#include"client_sqlite.h"
#include"logger.h"

#define ID  "H614CQAGLRMQTT_d"
#define Username  "H614CQAGLRMQTT_ds18b20_01;12010126;c6bca;1659326400000"
#define mqttHostUrl  "H614CQAGLR.iotcloud.tencentdevices.com"
#define passwd  "9dc7e01f4c3c5ce6f8aca02fe462342edadd58fcc6fd63d039a6868d00399529;hmacsha256"
#define KEEP_ALIVE 60
#define PORT  1883
#define TOPIC  "$shadow/operation/H614CQAGLR/MQTT_ds18b20_01"
//#define cjson  {\"type\": \"update\", \"state\": {\"reported\": {\"temperature\": 27}},\"version\": 1,\"clientToken\":\"clientToken\"}

static int g_stop=0;//定义运行标志决定时都需要结束
bool session=true;
#define MSG_MAX_SIZE 1024//缓冲区最大容量

void print_usage(char *progname);
void signal_stop(int signum);//信号

int main(int argc,char* argv[])
{
        int                     rv;
        struct  mosquitto       *mosq=NULL;
        char                    buff[MSG_MAX_SIZE];
        char                    buf[MSG_MAX_SIZE];
        int                     socket_fd=-1;
        int                     port=PORT;
        int                     opt;
        int                     daemon_run=0;
        char                    *get_ip;
        struct hostent          *get_host;
        float                   temperature;
        int                     log_fd;
        int                     stop_time=30;
        int                     mid;
        char                    *name="0004";
        char                    T_time[64];
        char                    *clientId=ID;
        char                    *hostname=mqttHostUrl;
        char                    *username=Username;
        char                    *topic=TOPIC;
        char                    *password=passwd;

        struct option   opts[]={
                {"daemon",no_argument,NULL,'d'},
                {"help", no_argument, NULL, 'H'},
                {"ip", required_argument, NULL,'i'},
                {"topic", required_argument, NULL,'t'},
                {"hostname", required_argument, NULL,'n'},
                {"port", required_argument, NULL,'p'},
                {"clientId", required_argument, NULL,'c'},
                {"username", required_argument, NULL,'u'},
                {"password", required_argument, NULL,'w'},
                {NULL,0,NULL,0},
        };
        while((opt=getopt_long(argc,argv,"dHi:t:n:p:c:u:w:",opts,NULL))!=-1)
        {
                switch(opt)
                {

                        case'd':
                                daemon_run=1;
                                break;
                        case 'H':
                                print_usage(argv[0]);
                                return 0;
                        case 'i':
                                get_ip = optarg;
                                break;
                        case 't':
                                topic = optarg;
                                break;

                        case 'n':
                                hostname = optarg;
                                break;

                        case 'p':
                                port = atoi(optarg);
                                break;

                        case 'c':
                                clientId = optarg;
                                break;

                        case 'u':
                                username = optarg;
                                break;

                        case 'w':
                                password = optarg;
                                break;
                        default:
                                break;

                }
        }

        if(hostname){
        get_host = gethostbyname(hostname);
        if( !get_host )
        {
            printf("gethostbyname() get ip failure:%s\n", strerror(errno));
            rv = -1;
        }

        get_ip = inet_ntoa(*(struct in_addr *)get_host->h_addr);
        printf("DNS ip is:%s\n", get_ip);
    }
        if(!port&&(!hostname||!get_ip)){
                print_usage(argv[0]);
                return 0;
        }
        /*日志*/
        if( logger_init("temperature.log", LOG_LEVEL_DEBUG) < 0){
                fprintf(stderr, "initial logger system failure\n");
                return 2;
        }
        if(daemon_run){
                /*设置守护进程*/
                 if ((daemon(1, 1)) < 0){
                    //printf("Deamon failure : %s\n", strerror(errno));
                      log_error("This is error level message!");
                      return 0;
                }
                printf("Program %s is running at the background now\n", argv[0]);
        }
        rv=mosquitto_lib_init();
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("mosquitto init failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        else{
                printf("mosquitto init successful\n");
        }
        mosq=mosquitto_new(clientId,session,NULL);

        if(!mosq){
                printf("new pub_test failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        else{
                printf("create mosquitto successful\n");
        }
        rv=mosquitto_username_pw_set(mosq,username,password);//在connect之前调用这个函数
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("set username and password failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
          rv=sqlite3_open("/home/xuhuinan1/ds18b20/mosquitto-2.0.9/tencent_temper.db",&db);
        if(rv!=SQLITE_OK)
                {

                        printf("open database failure:%s\n",strerror(errno));
                        sqlite3_close(db);

                }
        else
                {
                        printf("open database successful\n");
                        sqlite_create(db);
                }

        rv=mosquitto_connect(mosq,get_ip,port,KEEP_ALIVE);
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("mosquitto_connect failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        else{
                printf("mosquitto_connect successfully\n");
                rv=mosquitto_loop_start(mosq);
                if(rv!=MOSQ_ERR_SUCCESS){
                        printf("mosquitto_loop failure:%s\n",strerror(errno));
                        mosquitto_destroy(mosq);
                        mosquitto_lib_cleanup();
                }
                printf("loop ok!\n");
                signal(SIGTERM,signal_stop);
                while(!g_stop){
                        get_temperature(&temperature);
                        if(temperature<0)
                        {
                                printf("read temperature failure:%s\n",strerror(errno));
                                return -1;
                        }
                        else
                        {
                                printf("read temperature %f successful\n",temperature);
                                snprintf(buff,sizeof(buff), " {\"type\": \"update\", \"state\": {\"reported\": {\"temperature\": %.2f}},\"version\": 1,\"clientToken\":\"clientToken\"}",temperature);
                        }
			
                        printf("%s\n",buff);
                        get_time(T_time,sizeof(T_time));
                        if(T_time<0)
                        {
                                printf("get time  failure:%s\n",strerror(errno));
                                return -3;
                        }
                        else
                        {
                                printf("get time successful\n");
                        }
                        snprintf(buf,sizeof(buf),"%s-%s-%f",name,T_time,temperature);
                        rv=mosquitto_publish(mosq,NULL,topic,strlen(buff)+1,buff,0,0);
                        sqlite3_temp(buf);
                        if(rv!=MOSQ_ERR_SUCCESS){
                                printf("mosquitto_publish failure:%s\n",strerror(errno));
                                mosquitto_destroy(mosq);
                                mosquitto_lib_cleanup();
                        }
                        printf("publish information ok!\n");
                        sqlite_insert(db,buf);
                        sleep(stop_time);
                }
                sqlite3_close(db);

        }
}



void print_usage(char *progname)
{
    printf("%s usage: \n", progname);
    printf("-i(--ip): ip address.\n");
    printf("-d(--daemon): run background.\n");
    printf("-t(--topic):  MQTT topic.\n");
    printf("-n(--hostname): server domain name.\n");
    printf("-p(--port):  server port.\n");
    printf("-c(--clientid): specify clientid.\n");
    printf("-u(--username): specify username.\n");
    printf("-w(--password): specify user password.\n");
    printf("-h(--Help): print this help information.\n");

    return ;
}

void signal_stop(int signum)
{
        if(SIGTERM==signum)
        {
                printf("SIGTERM signal detected\n");
                g_stop=1;
        }
}

